<!DOCTYPE html>
<html>
<head>
<title>Pinhole Camera Diagram</title>
<style>
    body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        margin: 0;
    }
    canvas {
        border: 1px solid #eee;
    }
</style>
</head>
<body>

<canvas id="pinholeCanvas" width="700" height="500"></canvas>

<script>
    const canvas = document.getElementById('pinholeCanvas');
    const ctx = canvas.getContext('2d');

    // Style settings
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 2.5;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    // Coordinates and dimensions
    const yCenter = 220;
    const xObj = 100;
    const xPinhole = 350;
    const xImage = 570;
    const hObj = 100;
    const yObjTop = yCenter - hObj;
    const yObjBottom = yCenter + hObj;
    
    const pinholeDiameter = 30;
    const yPinholeTop = yCenter - pinholeDiameter / 2;
    const yPinholeBottom = yCenter + pinholeDiameter / 2;

    const L = xPinhole - xObj;
    const P = xImage - xPinhole;
    const hImg = hObj * (P / L);
    const yImgTop = yCenter - hImg;
    const yImgBottom = yCenter + hImg;
    
    const boxTop = yCenter - hObj - 20;
    const boxBottom = yCenter + hObj + 20;

    // Helper function to draw a filled arrow head
    function drawFilledArrow(ctx, fromx, fromy, tox, toy) {
        const headlen = 15;
        const dx = tox - fromx;
        const dy = toy - fromy;
        const angle = Math.atan2(dy, dx);
        ctx.beginPath();
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 7), toy - headlen * Math.sin(angle - Math.PI / 7));
        ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 7), toy - headlen * Math.sin(angle + Math.PI / 7));
        ctx.closePath();
        ctx.fill();
    }

    // --- Drawing starts here ---
    ctx.beginPath();

    // 1. Draw object and its representing triangle
    ctx.moveTo(xObj, yObjBottom);
    ctx.lineTo(xObj, yObjTop);
    ctx.moveTo(xObj, yObjTop);
    ctx.lineTo(xPinhole, yCenter);
    ctx.moveTo(xObj, yObjBottom);
    ctx.lineTo(xPinhole, yCenter);

    // 2. Draw pinhole barrier and camera box
    ctx.moveTo(xPinhole, boxTop);
    ctx.lineTo(xPinhole, yPinholeTop);
    ctx.moveTo(xPinhole, yPinholeBottom);
    ctx.lineTo(xPinhole, boxBottom);
    ctx.moveTo(xPinhole, boxTop);
    ctx.lineTo(xImage, boxTop);
    ctx.lineTo(xImage, boxBottom);
    ctx.lineTo(xPinhole, boxBottom);

    // 3. Draw image and its representing triangle
    ctx.moveTo(xPinhole, yCenter);
    ctx.lineTo(xImage, yImgBottom); 
    ctx.moveTo(xPinhole, yCenter);
    ctx.lineTo(xImage, yImgTop);
    ctx.moveTo(xImage, yImgTop);
    ctx.lineTo(xImage, yImgBottom);
    
    // 4. Draw central horizontal axis
    ctx.moveTo(xObj, yCenter);
    ctx.lineTo(xImage, yCenter);

    ctx.stroke();

    // Draw filled arrows for object and image
    drawFilledArrow(ctx, xObj, yObjBottom, xObj, yObjTop);
    drawFilledArrow(ctx, xImage, yImgTop, xImage, yImgBottom);

    // 5. Draw dimension lines and labels
    // Dimension for d (pinhole diameter)
    ctx.beginPath();
    const xDimD = xPinhole - 40;
    ctx.moveTo(xDimD, yPinholeTop);
    ctx.lineTo(xDimD, yPinholeBottom);
    ctx.moveTo(xDimD - 5, yPinholeTop);
    ctx.lineTo(xDimD + 5, yPinholeTop);
    ctx.moveTo(xDimD - 5, yPinholeBottom);
    ctx.lineTo(xDimD + 5, yPinholeBottom);
    ctx.stroke();
    ctx.font = 'italic 22px serif';
    ctx.fillText('d', xDimD - 20, yCenter);

    // Dimension for L and P
    ctx.beginPath();
    const yDimLP = 400;
    // Horizontal line
    ctx.moveTo(xObj, yDimLP);
    ctx.lineTo(xImage, yDimLP);
    // Ticks
    ctx.moveTo(xObj, yDimLP - 10);
    ctx.lineTo(xObj, yDimLP + 10);
    ctx.moveTo(xPinhole, yDimLP - 10);
    ctx.lineTo(xPinhole, yDimLP + 10);
    ctx.moveTo(xImage, yDimLP - 10);
    ctx.lineTo(xImage, yDimLP + 10);
    ctx.stroke();
    // Center plus symbol
    ctx.save();
    ctx.lineWidth = 4;
    ctx.beginPath();
    ctx.moveTo(xPinhole - 8, yDimLP);
    ctx.lineTo(xPinhole + 8, yDimLP);
    ctx.stroke();
    ctx.restore();
    
    // Labels L and P
    ctx.font = 'italic 22px serif';
    ctx.fillText('L', (xObj + xPinhole) / 2, yDimLP - 25);
    ctx.fillText('P', (xPinhole + xImage) / 2, yDimLP - 25);

    // 6. Draw Figure Caption
    ctx.font = 'bold 22px serif';
    ctx.fillText('Fig. 2.66', canvas.width / 2, 450);

</script>

</body>
</html>